package com.ecsolutions.soaClient;

/**
 * Created by tim on 2017/7/17.
 */

import com.ecsolutions.common.CinfigInfo;
import com.ecsolutions.dao.Workflow_DAO;
import org.apache.axis2.AxisFault;
import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ta.workflow.wcf.WorkflowStub;

import java.io.StringReader;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class WorkFlowServiceManager {

    private static Logger logger = Logger.getLogger(WorkFlowServiceManager.class);

    private String workflowWebServiceAddress;

    @Autowired
    private CinfigInfo baseConfig;

    @Autowired
    private Workflow_DAO wf_dao;

    // 启动工作流
    public String StartWorkflow(String jsonStr) {
        HashMap<String, Object> hRet;
        Object dataObj;
        String isSuc = "";
        String errMsg = "";

        String sRet = "";
        JSONObject jObj;
        logger.debug("start work flow data:[" + jsonStr + "]");
        try {
            // To do : 这里从request中获取param1,param2
            WorkflowStub.StartWorkFlowInfo param1 = new WorkflowStub.StartWorkFlowInfo();
//			KeyValueVariable[] param2 = new KeyValueVariable[]{};
            ArrayList<WorkflowStub.KeyValueVariable> lst = new ArrayList<WorkflowStub.KeyValueVariable>();

            String strUserName = "";
            String strRoleName = "";
            String strTaskName = "";
            String strDescription = "";
            String templateName = "";

            JSONParser parser = new JSONParser();
            StringReader read = new StringReader(jsonStr);
            JSONObject jsonData = (JSONObject) parser.parse(read);

            templateName = (String) jsonData.get("TemplateName");
            strUserName = (String) jsonData.get("UserId");
            strDescription = (String) jsonData.get("TaskDesc");
            strTaskName = (String) jsonData.get("TaskName");

            if (strRoleName == null || strRoleName.equals(""))
                strRoleName = "role1";
            if (strUserName == null || strUserName.equals(""))
                strUserName = "1";

            strRoleName = this.getUserRole(strUserName);
            param1.setTemplateName(templateName);
            param1.setDescription(strDescription);
            param1.setUserName(strUserName);
            param1.setTaskName(strTaskName);
            param1.setRoleName(strRoleName);


            // 获取模板的参数列表
            hRet = this.getTemplateVariables(templateName, strUserName, strRoleName);

            isSuc = (String) hRet.get("isSuc");

            if (isSuc.equals("true")) {
                dataObj = hRet.get("dataObj");
                WorkflowStub.GlobalVariable[] paramList = ((WorkflowStub.GetTemplateVariablesResponse) dataObj).getGlobalVariableList();//.getGlobalVariable();
                if (paramList != null) {
                    // 获取参数名->到request中获取参数值
                    String fldName = "";
                    String fldVal = "";
                    for (int i = 0; i < paramList.length; i++) {

                        fldName = paramList[i].getVariableKey();

                        if (fldName.equalsIgnoreCase("Global.ocr_filename")) {

                            String locName = (String) jsonData.get("ocr_filename");
                            fldVal = locName;
                        } else if (fldName.equalsIgnoreCase("Global.ocr_image")) {
                            String locCont = (String) jsonData.get("ocr_image");
                            fldVal = locCont;
                        } else {

                            fldVal = (String) jsonData.get("fld" + fldName);
                        }

                        if (fldVal == null) {
                            fldVal = "";
                        }

                        if (fldVal.toString().equals("")) {
                            fldVal = paramList[i].getDefaultValue();
                        }

                        WorkflowStub.KeyValueVariable k_val = new WorkflowStub.KeyValueVariable();
                        k_val.setVariableKey(fldName);
                        k_val.setVariableValue(fldVal);


                        lst.add(k_val);
                        //param2.addKeyValueVariable(k_val);

                    }
                }

            }


            //
            JSONArray json = new JSONArray();

            // /////////////////////////

            //KeyValueVariable[] param2 =(KeyValueVariable[]) lst.toArray();
            WorkflowStub.KeyValueVariable[] param2 = new WorkflowStub.KeyValueVariable[lst.size()];
            //lst.toArray(param2);


            hRet = startWorkflow(param1, param2);

            isSuc = (String) hRet.get("isSuc");
            errMsg = (String) hRet.get("errMsg");

            JSONObject jObjMain = new JSONObject();

            if (isSuc.equals("false")) {
                jObjMain.put("isSuc", "false");
                jObjMain.put("errMsg", errMsg);
                sRet = "[" + jObjMain.toString() + "]";

                return sRet;
            } else {

                jObjMain.put("isSuc", "true");

            }

            dataObj = hRet.get("dataObj");

            int iTaskId = 0;
            iTaskId = ((WorkflowStub.StartWorkflowResponse) dataObj).getTaskId();

            // ///////////////////////////////////
            jObjMain.put("taskId", Integer.toString(iTaskId));
            json.add(jObjMain);
            sRet = json.toString();
            return sRet;

        } catch (Exception e) {
            sRet = "[StartWorkflow][ERR]-" + e.toString();
            jObj = new JSONObject();
            jObj.put("isSuc", "false");
            jObj.put("errMsg", sRet);
            sRet = "[" + jObj.toString() + "]";
            logger.error(sRet);

        } finally {
            return sRet;
        }

    }

    // 获取工作流任务列表
    public String GetWorkItemList(String jsonStr) {
        String sRet = "";
        String strUserName = "1";
        String strUserRole = "role1";

        HashMap<String, Object> hRet;
        Object dataObj;
        String isSuc = "";
        String errMsg = "";

        String strStepType = "";
        String strStepState = "";

        JSONObject jObj;
        JSONParser parser = new JSONParser();
        StringReader read = new StringReader(jsonStr);
        JSONObject jsonData = null;
        try {
            jsonData = (JSONObject) parser.parse(read);
        } catch (Exception e) {
            e.printStackTrace();
        }

        TaskQueueWorkItem item = new TaskQueueWorkItem();
        // to do get parameter from request
        strUserName = (String) jsonData.get("userName");
        strStepType = (String) jsonData.get("stepType");
        strStepState = (String) jsonData.get("stepState");
        String strActive = (String) jsonData.get("bActive");

        strUserRole = this.getUserRole(strUserName);

        if (strActive == null)
            strActive = "true";

        if (strStepType == null || "".equals(strStepType.trim()))
            strStepType = "";

        if (strStepState == null || "".equals(strStepState.trim()))
            strStepState = "";


        if (strUserName == null || strUserName.equals("")) {
            strUserName = "1";
        }

        boolean isActive = true;
        if (!strActive.equals("true"))
            isActive = false;
        try {
            JSONArray json = new JSONArray();
            WorkflowStub.TaskItem[] tskList;

            hRet = getWorkItemList(strUserName, strUserRole, isActive, strStepType, strStepState);
            isSuc = (String) hRet.get("isSuc");
            errMsg = (String) hRet.get("errMsg");

            JSONObject jObjMain = new JSONObject();

            if (isSuc.equals("false")) {
                jObjMain.put("isSuc", "false");
                jObjMain.put("errMsg", errMsg);
                sRet = "[" + jObjMain.toString() + "]";
                return sRet;
            } else {
                jObjMain.put("isSuc", "true");
            }
            json.add(jObjMain);

            dataObj = hRet.get("dataObj");

            tskList = ((WorkflowStub.GetWorkItemListResponse) dataObj).getTaskItemList();//.getTaskItem();

            // ///////////////////////////////////
            if (tskList != null) {
                for (int i = 0; i < tskList.length; i++) {
                    jObj = new JSONObject();
                    item.setTaskStepID(tskList[i].getTaskStepID());
                    item.setStepType(tskList[i].getStepType());
                    item.setTitle(tskList[i].getTitle());
                    item.setRecipient(tskList[i].getRecipient());
                    item.setSubject(tskList[i].getSubject());
                    item.setMessage(tskList[i].getMessage());
                    item.setItemState(tskList[i].getItemState());


                    Calendar cal = Calendar.getInstance();
                    cal.setTime(tskList[i].getCreateTime());
//                    cal.setTime(tskList[i].getCreateTime().getTime());
                    item.setCreateTime(cal);

                    item.setTaskID(tskList[i].getTaskID());
                    item.setTaskName(tskList[i].getTaskName());


                    jObj.put("TaskStepID", item.getTaskStepID());
                    jObj.put("oldStepType", item.getStepType());

                    jObj.put("TaskID", item.getTaskID());
                    jObj.put("TaskName", item.getTaskName());


					/*
                     * 10-Information; 11-Response; 12-CheckPoint;
					 * 22-LaunchTAFAPPS; 23-LaunchUrl
					 */
                    switch (item.getStepType()) {
                        case 10:
                            jObj.put("StepType", "Information");
                            break;
                        case 11:
                            jObj.put("StepType", "Response");
                            break;
                        case 12:
                            jObj.put("StepType", "CheckPoint");
                            break;
                        case 22:
                            jObj.put("StepType", "LaunchTAFAPPS");
                            break;
                        case 23:
                            jObj.put("StepType", "LaunchUrl");
                            break;
                        default:
                            jObj.put("StepType", "Unknown");
                    }


                    if (item.getTitle() != null) {
                        jObj.put("Title", item.getTitle().toString());
                    } else {
                        jObj.put("Title", "");
                    }

                    if (item.getRecipient() != null) {
                        jObj.put("Recipient", item.getRecipient().toString());
                    } else {
                        jObj.put("Recinient", "");
                    }

                    if (item.getSubject() != null) {
                        jObj.put("Subject", item.getSubject().toString());
                    } else {
                        jObj.put("Subject", item.getSubject().toString());
                    }

                    if (item.getMessage() != null) {
                        jObj.put("Message", item.getMessage().toString());
                    } else {
                        jObj.put("Message", "");
                    }


                    jObj.put("oldItemState", item.getItemState());

                    switch (item.getItemState()) {
                        case 0:
                            jObj.put("ItemState", "Unknown");
                            break;
                        case 1:
                            jObj.put("ItemState", "WaitingForView");
                            break;
                        case 2:
                            jObj.put("ItemState", "UserInAction");
                            break;
                        case 3:
                            jObj.put("ItemState", "WaitForResponse");
                            break;
                        case 4:
                            jObj.put("ItemState", "Responsed");
                            break;
                    }

                    SimpleDateFormat fmt = new SimpleDateFormat(
                            "yyyy/MM/dd HH:mm:ss");

                    if (item.getCreateTime() != null)
                        jObj.put("CreateTime", fmt.format(item.getCreateTime().getTime()));

                    json.add(jObj);
                }
                sRet = json.toString();
                logger.debug("return task list=" + json);
            } else {
                sRet = "No Record!";
                jObj = new JSONObject();
                jObj.put("isSuc", "true");
                jObj.put("errMsg", sRet);
                sRet = "[" + jObj.toString() + "]";
            }

        } catch (Exception e) {
            sRet = "[GetWorkItemList][ERR]-" + e.toString();
            jObj = new JSONObject();
            jObj.put("isSuc", "false");
            jObj.put("errMsg", sRet);
            sRet = "[" + jObj.toString() + "]";

            logger.error("[WorkFlowServiceManager]" + sRet);
        } finally {
            return sRet;
        }
    }

    // 更新工作流任务
    public String UpdateWorkItem(String userName, String roleName, int taskStepId, int currentState, int newState, String selectedValue, WorkflowStub.KeyValueVariable[] pVal) {
        HashMap<String, Object> hRet;
        Object dataObj;
        String isSuc = "";
        String errMsg = "";

        String sRet = "";
        JSONObject jObj;
        try {
            JSONArray json = new JSONArray();

            // /////////////////////////
            hRet = this.updateWorkItem(userName, roleName, taskStepId,
                    currentState, newState, selectedValue, pVal);

            isSuc = (String) hRet.get("isSuc");
            errMsg = (String) hRet.get("errMsg");

            JSONObject jObjMain = new JSONObject();

            if (isSuc.equals("false")) {
                jObjMain.put("isSuc", "false");
                jObjMain.put("errMsg", errMsg);
                sRet = "[" + jObjMain.toString() + "]";
                return sRet;
            } else {
                jObjMain.put("isSuc", "true");
            }
            json.add(jObjMain);
            // ///////////////////////////////////

            sRet = json.toString();
            return sRet;

        } catch (Exception e) {
            sRet = "[UpdateWorkItem][ERR]-" + e.toString();
            jObj = new JSONObject();
            jObj.put("isSuc", "false");
            jObj.put("errMsg", sRet);
            sRet = "[" + jObj.toString() + "]";
            logger.error(sRet);

        } finally {
            return sRet;
        }

    }

    // 获取当前步骤taskstepid
    public String getCurrentTaskStepId(String strTaskId, String strUserName){
        String taskStepId = "";
        int taskId = 0;
        if (strTaskId != null && !"".equals(strTaskId) && isNumeric(strTaskId)){
            Integer it = new Integer(strTaskId);
            taskId = it.intValue();
        }
        if (strUserName == null || "".equals(strUserName)) {
            strUserName = "1";
        }
        String strUserRole = this.getUserRole(strUserName);
        HashMap<String, Object> hRet = this.getWorkItemList(strUserName,strUserRole,true,"","1");
        Object dataObj = hRet.get("dataObj");
        WorkflowStub.TaskItem[] taskItemList = ((WorkflowStub.GetWorkItemListResponse) dataObj).getTaskItemList();
        for (int i=0;i<taskItemList.length;++i){
            if (taskId == taskItemList[i].getTaskID()){
                taskStepId = String.valueOf(taskItemList[i].getTaskStepID());
            }
        }
        return taskStepId;
    }

    // StartWorkflowResponse
    private HashMap<String, Object> startWorkflow(WorkflowStub.StartWorkFlowInfo param1, WorkflowStub.KeyValueVariable[] param2) {

        HashMap<String, Object> hRet = new HashMap();
        hRet.put("isSuc", "false");

        WorkflowStub wfsstub;
        try {
            workflowWebServiceAddress = baseConfig.getWorkFlowUrl();
            wfsstub = new WorkflowStub(workflowWebServiceAddress);
            WorkflowStub.StartWorkflow gwcf = new WorkflowStub.StartWorkflow();
            // 这里对调用前代理对像赋值
            gwcf.setFlowInfo(param1);
            gwcf.setVarList(param2);

            try {
                WorkflowStub.StartWorkflowResponse ret;
                ret = wfsstub.startWorkflow(gwcf).get_return();
                if (ret.getReturnResult()) {
                    hRet.put("isSuc", "true");
                    hRet.put("dataObj", ret);
                } else {
                    logger.error("[startWorkflow][ERR]" + ret.getErrorMessage());
                    hRet.put("errMsg",
                            "[startWorkflow][ERR]" + ret.getErrorMessage());
                }
                return hRet;
            } catch (RemoteException e) {
                e.printStackTrace();
                logger.error("[startWorkflow][ERR]" + e.getMessage());
                hRet.put("errMsg", "[startWorkflow][ERR]" + e.getMessage());
            }

        } catch (AxisFault e) {
            e.printStackTrace();
            logger.error("[startWorkflow][ERR]" + e.getMessage());
            hRet.put("errMsg", "[startWorkflow][ERR]" + e.getMessage());
        }

        return hRet;

    }

    // GetTemplateVariablesResponse
    private HashMap<String, Object> getTemplateVariables(String wkTemplateName, String strUserName, String strRoleName) {
        HashMap<String, Object> hRet = new HashMap();
        hRet.put("isSuc", "false");

        String result = "";
        WorkflowStub wfsstub;


        try {
            workflowWebServiceAddress = baseConfig.getWorkFlowUrl();
            wfsstub = new WorkflowStub(workflowWebServiceAddress);
            WorkflowStub.GetTemplateVariables gwcf = new WorkflowStub.GetTemplateVariables();

            try {

                WorkflowStub.GetTemplateVariablesResponse ret;
                gwcf.setTemplateName(wkTemplateName);

                gwcf.setUserName(strUserName);
                gwcf.setRoleName(strRoleName);

                ret = wfsstub.getTemplateVariables(gwcf)
                        .get_return();

                if (ret.getReturnResult()) {
                    hRet.put("isSuc", "true");
                    hRet.put("dataObj", ret);

                } else {
                    logger.error("[getTemplateVariables][ERR]"
                            + ret.getErrorMessage());
                    hRet.put(
                            "errMsg",
                            "[getTemplateVariables][ERR]"
                                    + ret.getErrorMessage());
                }

                return hRet;
            } catch (RemoteException e) {
                e.printStackTrace();
                logger.error("[getTemplateVariables][ERR]" + e.getMessage());
                hRet.put("errMsg",
                        "[getTemplateVariables][ERR]" + e.getMessage());
            }

        } catch (AxisFault e) {
            e.printStackTrace();
            logger.error("[getTemplateVariables][ERR]" + e.getMessage());
            hRet.put("errMsg", "[getTemplateVariables][ERR]" + e.getMessage());
        }

        return hRet;
    }

    // GetWorkItemListResponse
    public HashMap<String, Object> getWorkItemList(String strUserName, String strRoleName, boolean isActive, String strStepType, String strStepState) {
        HashMap<String, Object> hRet = new HashMap();
        hRet.put("isSuc", "false");

        String result = "";

        WorkflowStub wfsstub;
        try {
            workflowWebServiceAddress = baseConfig.getWorkFlowUrl();
            wfsstub = new WorkflowStub(workflowWebServiceAddress);
            WorkflowStub.GetWorkItemList gwcf = new WorkflowStub.GetWorkItemList();
            gwcf.setUserName(strUserName);
            gwcf.setRoleName(strRoleName);
            gwcf.setIsActive(isActive);

            if (!strStepType.equals(""))
                gwcf.setStepType(strStepType);


            if (!strStepState.equals(""))
                gwcf.setStepState(strStepState);


            try {
                WorkflowStub.GetWorkItemListResponse ret;
                ret = wfsstub.getWorkItemList(gwcf).get_return();
                if (ret.getReturnResult()) {

                    hRet.put("isSuc", "true");
                    hRet.put("dataObj", ret);

                } else {
                    logger.error("[getWorkItemList][ERR]"
                            + ret.getErrorMessage());
                    hRet.put("errMsg",
                            "[getWorkItemList][ERR]" + ret.getErrorMessage());
                }
                return hRet;
            } catch (RemoteException e) {
                e.printStackTrace();
                logger.error("[getWorkItemList][ERR]" + e.getMessage());
                hRet.put("errMsg", "[getWorkItemList][ERR]" + e.getMessage());
            }

        } catch (AxisFault e) {
            e.printStackTrace();
            logger.error("[getWorkItemList][ERR]" + e.getMessage());
            hRet.put("errMsg", "[getWorkItemList][ERR]" + e.getMessage());
        }

        return hRet;
    }

    // UpdateWorkItemResponse
    private HashMap<String, Object> updateWorkItem(String userName, String roleName, int taskStepId, int currentState, int newState, String selectedValue, WorkflowStub.KeyValueVariable[] pVal) {
        HashMap<String, Object> hRet = new HashMap();
        hRet.put("isSuc", "false");
        WorkflowStub wfsstub;
        try {
            workflowWebServiceAddress = baseConfig.getWorkFlowUrl();
            wfsstub = new WorkflowStub(workflowWebServiceAddress);
            WorkflowStub.UpdateWorkItem gwcf = new WorkflowStub.UpdateWorkItem();
            // 这里对调用前代理对像赋值
            gwcf.setUserName(userName);
            gwcf.setTaskStepId(taskStepId);
            gwcf.setCurrentState(currentState);
            gwcf.setNewState(newState);
            gwcf.setRoleName(roleName);
            gwcf.setInputKeyVals(pVal);
            gwcf.setSelectedValue(selectedValue);

            try {
                WorkflowStub.UpdateWorkItemResponse ret;
                ret = wfsstub.updateWorkItem(gwcf).get_return();
                if (ret.getReturnResult()) {
                    hRet.put("isSuc", "true");
                    hRet.put("dataObj", ret);

                } else {
                    logger.error("[updateWorkItem][ERR]"
                            + ret.getErrorMessage());
                    hRet.put("errMsg",
                            "[updateWorkItem][ERR]" + ret.getErrorMessage());
                }
                return hRet;
            } catch (RemoteException e) {
                e.printStackTrace();
                logger.error("[updateWorkItem][ERR]" + e.getMessage());
                hRet.put("errMsg", "[updateWorkItem][ERR]" + e.getMessage());
            }

        } catch (AxisFault e) {
            e.printStackTrace();
            logger.error("[updateWorkItem][ERR]" + e.getMessage());
            hRet.put("errMsg", "[updateWorkItem][ERR]" + e.getMessage());
        }

        return hRet;

    }

    private String getUserRole(String usrID) {
        if (usrID == null) {
            logger.debug("usrID is null ");
            usrID = "";
        }
        String strRet = "role1";
        try {
            List<String> resultSet = wf_dao.getRoleByUser(usrID);
            if (resultSet.size() > 0) {
                strRet = resultSet.get(0);
            }
        } catch (Exception e) {
            logger.debug(e.toString());
            e.printStackTrace();
        } finally {
            return strRet;
        }
    }

    private boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if( !isNum.matches() ){
            return false;
        }
        return true;
    }

    public class TaskQueueWorkItem {
        private int TaskStepID;
        private int StepType;
        private String Title;
        private String Recipient;
        private String Subject;
        private String Message;
        private String ResponseDomainValues;
        private boolean IsActive;
        private int ItemState;
        private String SelectedValue;
        private Calendar CreateTime;
        private Calendar CompleteTime;
        private String ServiceName;
        private String TaskName;
        private int TaskID;

        public int getTaskStepID() {
            return TaskStepID;
        }

        public void setTaskStepID(int taskStepID) {
            TaskStepID = taskStepID;
        }

        public int getStepType() {
            return StepType;
        }

        public void setStepType(int stepType) {
            StepType = stepType;
        }

        public String getTitle() {
            return Title;
        }

        public void setTitle(String title) {
            Title = title;
        }

        public String getRecipient() {
            return Recipient;
        }

        public void setRecipient(String recipient) {
            Recipient = recipient;
        }

        public String getSubject() {
            return Subject;
        }

        public void setSubject(String subject) {
            Subject = subject;
        }

        public String getMessage() {
            return Message;
        }

        public void setMessage(String message) {
            Message = message;
        }

        public String getResponseDomainValues() {
            return ResponseDomainValues;
        }

        public void setResponseDomainValues(String responseDomainValues) {
            ResponseDomainValues = responseDomainValues;
        }

        public boolean isActive() {
            return IsActive;
        }

        public void setActive(boolean active) {
            IsActive = active;
        }

        public int getItemState() {
            return ItemState;
        }

        public void setItemState(int itemState) {
            ItemState = itemState;
        }

        public String getSelectedValue() {
            return SelectedValue;
        }

        public void setSelectedValue(String selectedValue) {
            SelectedValue = selectedValue;
        }

        public Calendar getCreateTime() {
            return CreateTime;
        }

        public void setCreateTime(Calendar createTime) {
            CreateTime = createTime;
        }

        public Calendar getCompleteTime() {
            return CompleteTime;
        }

        public void setCompleteTime(Calendar completeTime) {
            CompleteTime = completeTime;
        }

        public String getServiceName() {
            return ServiceName;
        }

        public void setServiceName(String serviceName) {
            ServiceName = serviceName;
        }

        public String getTaskName() {
            return TaskName;
        }

        public void setTaskName(String taskName) {
            TaskName = taskName;
        }

        public int getTaskID() {
            return TaskID;
        }

        public void setTaskID(int taskID) {
            TaskID = taskID;
        }
    }
}
